using System;
using System.Text;

namespace LambdaGp.Core
{
    public abstract class Operator
    {
        protected Operator(string name)
        {
            Name = name;
        }

        public abstract int Arity { get; }
        public string Name { get; set; }
        public virtual string AsToken { get { return Name; } }
        public virtual string CompactCode { get; set; }
        public virtual bool RequiresParameterMutation { get { return false; } }
        public bool LimitUsageToPrexistingItems { get; set; }

        public abstract Func<double> CompileToFunc(Individual individual, OperatorNode operatorNode);

        public override string ToString()
        {
            return string.Format("{0} ({1})", Name, base.ToString());
        }

        public virtual void AddToStorage(Individual individual)
        {
        }

        public virtual bool MatchesToken(string token, TokenPriority tokenPriority)
        {
            if (tokenPriority != TokenPriority.Primary)
            {
                return false;
            }
            return token.ToLower() == Name.ToLower();
        }

        public virtual bool MatchesCompactToken(string compactToken)
        {
            if (CompactCode == null)
            {
                throw new InvalidOperationException(string.Format("{0} must have a compact code!", Name));
            }

            return CompactCode == compactToken;
        }

        public virtual Operator GetFromToken(string token)
        {
            return this;
        }

        public virtual Operator ReplaceIfRequired()
        {
            return this;
        }

        public virtual void AddCompactString(StringBuilder stringBuilder)
        {
            if (CompactCode == null)
            {
                throw new InvalidOperationException(string.Format("{0} must have a compact code!", Name));
            }

            stringBuilder.Append(CompactCode);
        }
    }
}
